package com.strongbj.iot.devices.dam.sub.dacai.response.handle;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.strongbj.core.device.DeviceManager;
import com.strongbj.core.device.IDevice;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.message.DAMMessageFactory;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessage;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessageType;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnEntity;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnFactory;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnTextControlEntity;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnTextControlFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

/**
 * 根据IP查找设备编号
 * 
 * @author yuzhantao
 *
 */
public class FindDeviceCodeByIP implements IMessageHandle<DaCaiMessage, Object> {
	private static Logger logger = LogManager.getLogger(FindDeviceCodeByIP.class.getName());
	protected final static String COMMAND_CODE = "B111"; // 打开页面命令的编号
	protected final static String DEFAULT_DEVICE_CODE = "000000"; // 设备默认编号
	protected final static long MAX_TIMEOUT = 2000; // 最大超时时间
	protected final static byte TEXT_CONTROL_TYPE = 17; //  文本控件类型
	protected final static byte BUTTON_CONTROL_TYPE = 16; //  按钮控件类型
	protected DAMMessageFactory damMessageFactory = new DAMMessageFactory();

	protected String findIp = "";
	protected int clickButtonId = 0;
	protected long prevUpdateTime;

	@Override
	public boolean isHandle(DaCaiMessage t) {
		if (t.getMessageType() == DaCaiMessageType.System && t.getCommand().equals(COMMAND_CODE)) {
			ScreenReturnEntity sr = ScreenReturnFactory.create(t.getDatas());

			// 如果屏幕id为8，(控件类型为按钮，按钮id为9或12) 或(控件类型为文本，文本id为6或8)
			if (sr.getScreenId() == 8 && ((sr.getControlType() == BUTTON_CONTROL_TYPE
					&& (sr.getControlId() == 9 || sr.getControlId() == 12))
					|| (sr.getControlType() == TEXT_CONTROL_TYPE
							&& (sr.getControlId() == 6 || sr.getControlId() == 8))))
				return true;
		}
		return false;
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, DaCaiMessage t) {
		ScreenReturnEntity sr = ScreenReturnFactory.create(t.getDatas());
		if (sr.getControlType() == BUTTON_CONTROL_TYPE) { // 如果是按钮
			this.clickButtonId = sr.getControlId();
		} else if (sr.getControlType() == TEXT_CONTROL_TYPE) { // 如果是文本框
			ScreenReturnTextControlEntity textEntity = ScreenReturnTextControlFactory.create(t.getDatas());
			this.findIp = new String(ByteUtil.hexStringToBytes(textEntity.getContent())).replace("\"", "").replace("\0",
					"").trim();
		}

		if (System.currentTimeMillis() - this.prevUpdateTime > MAX_TIMEOUT) {
			if (this.prevUpdateTime == 0) {
				this.prevUpdateTime = System.currentTimeMillis();
			} else {
				this.clearDatas();
			}
			return null;
		} else {
			this.prevUpdateTime = System.currentTimeMillis();
		}

		if (this.clickButtonId == 0 || this.findIp == "")
			return null;

		IDevice dev = DeviceManager.getInstance().findDevice(this.findIp);
		ITaskManager taskManager = DAMManager.getTaskManager(t.getDamCode()); // 获取发送数据的任务管理类
		if (dev == null) {
			sendShowDialogMessage(taskManager, ctx, t.getDamCode(), "没有找到" + this.findIp + "的相关设备编号!");
		} else {
			sendDeviceCodeToControl(taskManager, ctx, t.getDamCode(), dev.getDeviceCode(), sr);
		}

//		// TODO 测试绑定设备
//		try {
//			logger.info("========================================================================");
//			for (Entry<?, ?> item : DeviceManager.getInstance().getDeviceMap().entrySet()) {
//				try {
//					IDevice tempDev = (IDevice) item.getValue();
//					logger.info("遍历设备 key={}  ip={}  code={}",item.getKey(), tempDev.getDeviceIp(), tempDev.getDeviceCode());
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//			}
//			logger.info("========================================================================");
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

		this.clearDatas();
		return null;
	}

	protected void clearDatas() {
		this.findIp = "";
		this.clickButtonId = 0;
		this.prevUpdateTime = 0;
	}

	/**
	 * 发送显示对话框信息命令
	 * 
	 * @param taskManager 任务管理实体
	 * @param ctx         socket通讯实体
	 * @param damCode     DAM设备编号
	 * @param msg         对话框中要显示的信息
	 */
	private void sendShowDialogMessage(ITaskManager taskManager, ChannelHandlerContext ctx, String damCode,
			String msg) {
		// 发送信息到对话框用于显示
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				try {
					Channel channel = ctx.channel();
					if (channel != null && channel.isActive()) {
						StringBuffer sb = new StringBuffer("EEB11000090001");
						sb.append(ByteUtil.byteArrToHexString(msg.getBytes("GBK")));
						sb.append("FFFCFFFF");
						byte[] datas = message2Bytes(damCode, (byte) 0xFF, ByteUtil.hexStringToBytes(sb.toString()));
						ByteBuf bs = Unpooled.copiedBuffer(datas);
						ChannelFuture cf = channel.writeAndFlush(bs);
						cf.addListener(new ChannelFutureListener() {

							@Override
							public void operationComplete(ChannelFuture future) throws Exception {
								if (future.isSuccess()) {
									logger.info("DAM自动下发设置“绑定设备编号”对话框信息命令成功，显示内容：{} 下发命令={}  ", msg,
											ByteUtil.byteArrToHexString(datas, true));
								} else {
									logger.error("DAM自动下发设置“绑定设备编号”对话框信息命令失败，显示内容：{} 下发命令={}  ", msg,
											ByteUtil.byteArrToHexString(datas, true));
								}
							}
						});
					} else {
						logger.error("主机没有找到指定channel");
					}
				} catch (Exception e) {
					logger.error(e);
				}
			}
		});
		// 打开对话框窗口
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				Channel channel = ctx.channel();
				if (channel != null && channel.isActive()) {
					byte[] showDialogCommandDatas = { (byte) 0xEE, (byte) 0xB1, (byte) 0x00, (byte) 0x00, (byte) 0x09,
							(byte) 0xFF, (byte) 0xFC, (byte) 0xFF, (byte) 0xFF };
					byte[] datas = message2Bytes(damCode, (byte) 0xFF, showDialogCommandDatas);
					ByteBuf bs = Unpooled.copiedBuffer(datas);
					ChannelFuture cf = channel.writeAndFlush(bs);
					cf.addListener(new ChannelFutureListener() {

						@Override
						public void operationComplete(ChannelFuture future) throws Exception {
							if (future.isSuccess()) {
								logger.info("DAM自动下发打开“绑定设备编号”对话框命令成功，下发命令={}  ",
										ByteUtil.byteArrToHexString(datas, true));
							} else {
								logger.error("DAM自动下发打开“绑定设备编号”对话框命令失败，下发命令={}  ",
										ByteUtil.byteArrToHexString(datas, true));
							}
						}
					});
				} else {
					logger.error("主机没有找到指定channel");
				}
			}
		});
	}

	/**
	 * 发送设备编号到绑定界面
	 * 
	 * @param taskManager 任务管理实体
	 * @param ctx         socket通讯实体
	 * @param damCode     DAM设备编号
	 * @param deviceCode  查找的设备编号
	 */
	private void sendDeviceCodeToControl(ITaskManager taskManager, ChannelHandlerContext ctx, String damCode,
			String deviceCode, ScreenReturnEntity sr) {
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				try {
					Channel channel = ctx.channel();
					if (channel != null && channel.isActive()) {
						StringBuffer sb = new StringBuffer("EEB110000800");
						// 根据点击的按钮ip来设置不同的文本控件显示内容
						if (sr.getControlId() == 9) {
							sb.append("06");
						} else if (sr.getControlId() == 12) {
							sb.append("08");
						}
						sb.append(ByteUtil.byteArrToHexString(deviceCode.getBytes("GBK")));
						sb.append("FFFCFFFF");
						byte[] datas = message2Bytes(damCode, (byte) 0xFF, ByteUtil.hexStringToBytes(sb.toString()));
						ByteBuf bs = Unpooled.copiedBuffer(datas);
						ChannelFuture cf = channel.writeAndFlush(bs);
						cf.addListener(new ChannelFutureListener() {

							@Override
							public void operationComplete(ChannelFuture future) throws Exception {
								if (future.isSuccess()) {
									logger.info("DAM自动将查找到的设备编号更新到“绑定设备编号”界面中成功，查找到的设备编号：{} 下发命令={}  ", deviceCode,
											ByteUtil.byteArrToHexString(datas, true));
								} else {
									logger.error("DAM自动将查找到的设备编号更新到“绑定设备编号”界面中失败，查找到的设备编号：{} 下发命令={}  ", deviceCode,
											ByteUtil.byteArrToHexString(datas, true));
								}
							}
						});
					} else {
						logger.error("主机没有找到指定channel");
					}
				} catch (Exception e) {
					logger.error(e);
				}
			}
		});
	}

	/**
	 * 网络参数对象转byte数组
	 * 
	 * @param deviceCode 发送到的设备编号
	 * @param command    发送的命令编码
	 * @param datas      发送的数据
	 * @return 要发送的数据
	 */
	private byte[] message2Bytes(String deviceCode, byte command, byte[] datas) {
		// 创建设置目标服务器的指令
		byte[] retDatas = damMessageFactory.createDAMMessage(ByteUtil.longToBytes(System.currentTimeMillis()),
				deviceCode, // 设备编号
				(byte) 0, // 设备类型，默认填0
				(byte) 0, // 版本号，默认填0
				command, // 命令
				datas // 空参数
		); // 通过dam消息工厂获取指令
		return retDatas;
	}
}
